package com.wuwei.elearning.question.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.wuwei.elearning.exception.ElearningMysqlException;
import com.wuwei.elearning.question.domain.*;
import com.wuwei.elearning.question.mapper.*;
import com.wuwei.elearning.question.service.SelfTestService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wuwei.elearning.question.vo.TestVo;
import com.wuwei.elearning.setting.domain.User;
import com.wuwei.elearning.setting.mapper.UserMapper;
import com.wuwei.elearning.utils.result.Result;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 学员自我练习时，用于保存自测记录试卷的表 服务实现类
 * </p>
 *
 * @author wuwei
 * @since 2024-04-09
 */
@Service
public class SelfTestServiceImpl extends ServiceImpl<SelfTestMapper, SelfTest> implements SelfTestService {

    @Resource
    private ChapterMapper chapterMapper;

    @Resource
    private SubjectMapper subjectMapper;

    @Resource
    private QuestionMapper questionMapper;

    @Resource
    private SelfTestRelationQuestionMapper selfTestRelationQuestionMapper;

    @Resource
    private SelfTestMapper selfTestMapper;

    @Resource
    private UserMapper userMapper;

    @Resource
    private SelfTestResultMapper selfTestResultMapper;

    @Resource
    private SelfTestAnswerMapper selfTestAnswerMapper;

    /**
     * 自我测试生成考题的方法，该方法其实就是向self_test插入一条记录，然后将self_test和question表关联上，也就是向self_test_relation_question插入数条记录
     * @param selectedId 如果小于10000，则为chapter表中的id字段，如果大于10000，则为subject表的id加上10000
     * @param account user表的account，也就是用户的账号
     @ param testNum 试题数量
     * @return 返回self_test表内刚插入的主键的id
     */
    @Override
    @Transactional
    public Long batchInsert(Long selectedId, Long account,Integer testNum) {
        LambdaQueryWrapper<Question> queryWrapper = new LambdaQueryWrapper<>();
        SelfTest selfTest = new SelfTest();
        if (selectedId<10000){
            Chapter chapter = chapterMapper.selectById(selectedId);
            queryWrapper.eq(Question::getChapter,chapter.getName());
            selfTest.setSelectedId(selectedId);
        } else {
            selfTest.setSelectedId(selectedId);
            selectedId = selectedId - 10000;
            Subject subject = subjectMapper.selectById(selectedId);
            queryWrapper.eq(Question::getSubject,subject.getName());
        }
        List<Question> questions = questionMapper.selectList(queryWrapper);
        //todo 根据出题数量新增self_test表和self_test_relation_question表
        int collectionSize = questions.size();
        if (testNum> collectionSize) {
            throw new ElearningMysqlException(30003,"出题数量不得大于该科目总数："+ collectionSize +"！");
        }
        Random random = new Random();
        Set<Long> selectedElements = new HashSet<>();
        while (selectedElements.size()<testNum){
            int randomIndex = random.nextInt(collectionSize);
            Long id = questions.get(randomIndex).getId();
            selectedElements.add(id);
        }

        //向self_test插入一条记录

        LambdaQueryWrapper<User> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.eq(User::getAccount,account);
        User user = userMapper.selectOne(queryWrapper1);
        Long id;

        selfTest.setCreateBy(account);
        selfTest.setCreateTime(LocalDateTime.now());
        selfTest.setTestTime(testNum*60);
        selfTest.setUserName(user.getName());

        int insert = selfTestMapper.insert(selfTest);
        if (insert==1) {
            id = selfTest.getId();
            //向self_test_relation_question插入数条记录
            selectedElements.forEach(s->{
                SelfTestRelationQuestion selfTestRelationQuestion = new SelfTestRelationQuestion();
                selfTestRelationQuestion.setQuestionId(s);
                selfTestRelationQuestion.setSelfTestId(id);
                selfTestRelationQuestionMapper.insert(selfTestRelationQuestion);
            });
            return id;
        }else {
            throw new ElearningMysqlException(30003,"出题失败！");
        }
    }
    /**
     * 获取自我测试生成的考题的方法
     * @Param selfTestId self_test表的主键
     * @Param account user表的account
     */
    @Override
    public Map<String, Object> batchGet(Long selfTestId, Long account) {
        //todo 后期要在这里检查考试是否考过该套试卷
        SelfTest selfTest = selfTestMapper.selectById(selfTestId);
        if (selfTest==null) {
            throw new ElearningMysqlException(30002,"题目编号不正确！");
        }
        else {
            Integer testTime = selfTest.getTestTime();
            LambdaQueryWrapper<SelfTestRelationQuestion> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(SelfTestRelationQuestion::getSelfTestId,selfTestId);
            List<SelfTestRelationQuestion> selfTestRelationQuestions = selfTestRelationQuestionMapper.selectList(queryWrapper);
            List<Question> result = new ArrayList<>();
            selfTestRelationQuestions.forEach(a->{
                Long questionId = a.getQuestionId();
                Question question = questionMapper.selectById(questionId);
                result.add(question);
            });
            Map<String,Object> map = new HashMap<>();
            map.put("result",result);
            map.put("time",testTime);
            return map;
        }
    }

    /**
     * 考完提交试卷
     * 1.添加1条记录到self_test_result表
     * 2.添加数条记录到self_test_answer表
     * @param testVo
     * @param account
     * @return
     */
    @Transactional
    @Override
    public Result<String> submit(TestVo testVo, Long account) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getAccount,account);
        User user = userMapper.selectOne(queryWrapper);
        //todo
        SelfTestResult selfTestResult = new SelfTestResult();
        selfTestResult.setAccount(account);
        selfTestResult.setCreateTime(LocalDateTime.now());
        selfTestResult.setScore(testVo.getScore());
        selfTestResult.setSelfTestId(testVo.getQuestionItemId());
        selfTestResult.setUsername(user.getName());
        // 将秒数转换为Duration对象
        Duration duration = Duration.ofSeconds(testVo.getSeconds());
        LocalTime usedTime = LocalTime.MIDNIGHT.plus(duration);
        selfTestResult.setUsedTime(usedTime);
        int insert = selfTestResultMapper.insert(selfTestResult);
        if (insert==1) {
            List<Long> questionIds = testVo.getIds();
            List<List<String>> allAnswers = testVo.getAllAnswers();
            for (int i = 0; i < allAnswers.size(); i++) {
                List<String> a = allAnswers.get(i);
                SelfTestAnswer selfTestAnswer = new SelfTestAnswer();
                selfTestAnswer.setSelfTestId(testVo.getQuestionItemId());
                selfTestAnswer.setUserName(testVo.getName());
                selfTestAnswer.setUserAccount(account);
                List<String> collect = a.stream().filter(b->!"".equals(b)).collect(Collectors.toList());
                if (collect.size()==1) {
                    selfTestAnswer.setSelected(collect.get(0));
                }
                if (collect.size()>1) {
                    String selected = String.join("+", collect);
                    selfTestAnswer.setSelected(selected);
                }
                selfTestAnswer.setQuestionId(questionIds.get(i));
                selfTestAnswerMapper.insert(selfTestAnswer);
            }
            return Result.ok("您的得分是"+testVo.getScore());
        } else {
            throw new ElearningMysqlException(30001,"self_test_result表添加记录失败！");
        }
    }

    /**
     * 删除self_test,self_test_answer,self_test_relation_question,self_test_result四张表
     * @param selfTestId selfTestId self_test的主键
     * @param account user表的account字段，账号
     */
    @Override
    @Transactional
    public void deleteById(Long selfTestId, Long account) {
        //1.删除self_test表
        selfTestMapper.deleteById(selfTestId);
        //2.删除self_test_answer表
        LambdaQueryWrapper<SelfTestAnswer> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.eq(SelfTestAnswer::getSelfTestId,selfTestId).eq(SelfTestAnswer::getUserAccount,account);
        selfTestAnswerMapper.delete(queryWrapper1);
        //3.删除self_test_result表
        LambdaQueryWrapper<SelfTestResult> queryWrapper2 = new LambdaQueryWrapper<>();
        queryWrapper2.eq(SelfTestResult::getSelfTestId,selfTestId).eq(SelfTestResult::getAccount,account);
        selfTestResultMapper.delete(queryWrapper2);
        //4.删除self_test_relation_question表
        LambdaQueryWrapper<SelfTestRelationQuestion> queryWrapper3 = new LambdaQueryWrapper<>();
        queryWrapper3.eq(SelfTestRelationQuestion::getSelfTestId,selfTestId);
        selfTestRelationQuestionMapper.delete(queryWrapper3);
    }


}
